﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using blackhouse.Currencies;
using System.Web;
using blackhouse.BlackApart.Business;
using System.Globalization;
using System.Configuration;

namespace blackhouse.BlackApart.Web.Modules {
    public class DisplayCurrency {

        private double value;
        private int precision;
        private const string CURRENCY_KEY = "Currency";
        //string fallbackCurrencyCode = "PLN";

        /// <summary>
        /// Reprezentuje cenę w aktualnej walucie
        /// </summary>
        public Currency Currency { get; private set; }
        public string ToCurrencyCode { get; private set; }
        public bool Current { get; private set; }

        public DisplayCurrency() : this(0, 2) { }

        public DisplayCurrency(double value, int precision) {
            this.value = value;
            this.precision = precision;

            //if (CultureInfo.CurrentCulture.Name != "pl-PL")
            //    this.fallbackCurrencyCode = "EUR";
        }

        //private DisplayCurrency(double value, int precision, string toCode) {
        //    this.value = value;
        //    this.precision = precision;
        //    this.ToCurrencyCode = toCode;


        //    string toC = "PLN";
        //    if (CultureInfo.CurrentCulture.Name != "pl-PL")
        //        toC = "EUR";
        //    this.Currency = new Currency(this.value,"PLN",this.precision).ToCurrency(this.ToCurrencyCode,toc)
        //}

        #region Methods

        public void Load() {
            this.ToCurrencyCode = this.GetCurrentCurrency();

            string toC = "PLN";
            if (CultureInfo.CurrentCulture.Name != "pl-PL")
                toC = "EUR";
            this.Currency = new Currency(this.value, "PLN", this.precision).ToCurrency(this.ToCurrencyCode, toC);
            this.Current = true;
        }

        public List<DisplayCurrency> GetCurrencies() {
            List<string> currencies = null;
            string cnfCurrencies = ConfigurationManager.AppSettings["Currencies"];
            if (!string.IsNullOrEmpty(cnfCurrencies))
                currencies = cnfCurrencies.Split(',').ToList();
            else
                currencies = this.Currency.GetSupportedCurrencies().ToList();

            if (!currencies.Contains(this.Currency.Code.ISOCode))
                currencies.Add(this.Currency.Code.ISOCode);

            List<DisplayCurrency> dispCurrencies = new List<DisplayCurrency>(currencies.Count);
            foreach (string currencyCode in currencies) {
                DisplayCurrency currency = new DisplayCurrency();
                currency.value = this.value;
                currency.precision = this.precision;
                currency.ToCurrencyCode = currencyCode;
                currency.Currency = new Currency(this.value, "PLN", this.precision).ToCurrency(currencyCode);
                currency.Current = currencyCode == this.Currency.Code.ISOCode;
                dispCurrencies.Add(currency);
            }
            return dispCurrencies;
        }

        public static string GetUserCurrency() {
            DisplayCurrency dc = new DisplayCurrency(1, 2);
            return dc.GetCurrentCurrency();
        }

        public string GetCurrentCurrency() {
            string currency = "";

            currency = this.GetCurrencyFromSession();
            if (!string.IsNullOrEmpty(currency))
                return currency;

            currency = this.GetCurrencyFromCookie();
            if (!string.IsNullOrEmpty(currency)) {
                this.SetCurrencyToSession(currency);
                return currency;
            }

            currency = this.GetCurrencyAssociatedToAppLang();

            if (string.IsNullOrEmpty(currency)) {
                try {
                    currency = this.GetCurrencyFromUserLanguage();
                } catch (Exception) {
                    currency = "";
                }
            }
            if (string.IsNullOrEmpty(currency))
                currency = Factory.Instance().GetCompany().GetCurrentUserCurrency().Code.ISOCode;

            return currency;
        }

        public bool ReceiveRequest(string newCurrency) {
            if (!string.IsNullOrEmpty(newCurrency)) {
                if (Currencies.Currency.Verify(newCurrency)) {
                    this.SetCurrencyToSession(newCurrency);
                    this.SetCurrencyToCookie(newCurrency);
                }
                return true;
            }
            return false;
        }

        private void SetCurrencyToCookie(string currencyCode) {
            HttpCookie cook = HttpContext.Current.Request.Cookies[CURRENCY_KEY];
            if (cook == null || cook.Value != currencyCode) {
                cook = HttpContext.Current.Response.Cookies[CURRENCY_KEY];
                if (cook == null) {
                    cook = new HttpCookie(CURRENCY_KEY, currencyCode);
                    cook.Expires = DateTime.Now.AddDays(120);
                    HttpContext.Current.Response.Cookies.Add(cook);
                } else HttpContext.Current.Response.Cookies[CURRENCY_KEY].Value = currencyCode;
            }
        }

        private string GetCurrencyFromCookie() {
            HttpCookie cook = HttpContext.Current.Request.Cookies[CURRENCY_KEY];
            if (cook != null && Currencies.Currency.Verify(cook.Value)) {
                return cook.Value;
            } else return "";
        }

        private void SetCurrencyToSession(string currencyCode) {
            if (HttpContext.Current == null || HttpContext.Current.Session == null) return;
            HttpContext.Current.Session[CURRENCY_KEY] = currencyCode;
        }

        private string GetCurrencyFromSession() {
            if (HttpContext.Current == null || HttpContext.Current.Session == null) return string.Empty;
            object v = HttpContext.Current.Session[CURRENCY_KEY];
            if (v == null)
                return string.Empty;
            else
                return v.ToString();
        }

        private string GetCurrencyAssociatedToAppLang() {
            string currency = ConfigurationManager.AppSettings["currency-" + CultureInfo.CurrentCulture.Name.Substring(0, 2)];
            if (!string.IsNullOrEmpty(currency) && currency.Length == 3) return currency;
            Currencies.Currency c = Currencies.Currency.FromCultureInfo(CultureInfo.CurrentCulture);
            if (c != null) return c.Code.ISOCode;
            else return String.Empty;
        }

        private string GetCurrencyFromUserLanguage() {
            if (HttpContext.Current == null || HttpContext.Current.Request == null) return "";

            string[] languages = HttpContext.Current.Request.UserLanguages;
            for (int xl = 0; xl < languages.Length; xl++) {
                string language = languages[xl].Split(';')[0];
                try {
                    CultureInfo ci = new CultureInfo(language);
                    if (!ci.IsNeutralCulture) {
                        Currencies.Currency c = Currencies.Currency.FromCultureInfo(ci);
                        if (c != null) return c.Code.ISOCode;
                    }
                } catch (Exception) { }
            }
            return "";
        }

        //public static string ReadUserCurrencyFromCookie() {
        //    HttpCookie cook = HttpContext.Current.Request.Cookies[CURRENCY_KEY];
        //    if (cook != null && Currencies.Currency.Verify(cook.Value))
        //        return cook.Value;
        //    else
        //        return "";
        //}

        #endregion

    }
}
